#pragma once

#include <iostream>
#include <string>
#include <pthread.h>
#include <functional>
#include "Sock.hpp"

static const uint16_t defaultport=8888;

using func_t = std::function<std::string(const std::string&)>; //输入request得到response


class HttpServer;
class ThreadData
{
public:
	ThreadData(int sock, const std::string& ip, const uint16_t port, HttpServer* tsvrp)
		:_sock(sock)
		,_ip(ip)
		,_port(port)
		,_tsvrp(tsvrp)
	{}

	~ThreadData(){}

public:
	int _sock;
	std::string _ip;
	uint16_t _port;
	HttpServer *_tsvrp;
};

class HttpServer
{
public:
	HttpServer(func_t f, int port = defaultport)
		: _port(port)
		, _func(f)
	{}
	~HttpServer()
	{}

	void InitServer()
	{
		logMessage(DEBUG, "InitServer success.");
		_listensock.Socket();
		_listensock.Bind(_port);
		_listensock.Listen();
	}

	void HandlerHttpRequest(int sock)
	{
		std::string request;
		char buffer[4096];
		ssize_t s = recv(sock, buffer, sizeof(buffer), 0);//我们假设我们能一次读完
		if(s > 0)
		{
			buffer[s] = '\0';
			request = buffer;
			std::string response = _func(request);
			send(sock, response.c_str(), response.size(), 0);
		}
		else
		{
			logMessage(INFO, "client quit...");
		}
	}

	static void* threadRoutine(void* args)
	{
		logMessage(DEBUG, "Create new Thread success, running now.");
		pthread_detach(pthread_self());
		ThreadData* td = static_cast<ThreadData*>(args);

		td->_tsvrp->HandlerHttpRequest(td->_sock);
		close(td->_sock);

		delete td;
		return nullptr;
	}

	void Start()
	{
		logMessage(DEBUG, "Start http server.");
		//循环去Accept
		for(;;)
		{
			std::string clientip;
			uint16_t clientport;
			int sock = _listensock.Accept(&clientip, &clientport);
			if(sock < 0) continue;

			logMessage(DEBUG, "Accept a connect from [%s:%d]", clientip.c_str(), clientport);

			pthread_t tid;
			ThreadData* td = new ThreadData(sock, clientip, clientport, this);

			pthread_create(&tid, nullptr, threadRoutine, td);
			
		}
	}

	

private:
	int _port;
	Sock _listensock;
	func_t _func;
};
